'''
Created on 2010/07/06

@author: yukiyonezawa
'''

from pyrfid.Util.Util import Util
import binascii

class Encoder(object):
    
    def __init__(self):
        pass
    
    @staticmethod
    def lengthEncode(length):
        if length < 16:
            lenHex = '0' + hex(length)[2:].upper()
        elif length < 128:
            lenHex = hex(length)[2:].upper()
        else:
            subLen = hex(length)[2:].upper()
            if len(subLen) % 2 == 1:
                subLen = '0' + subLen
            headLen = hex(128 + len(subLen)/2)[2:].upper()
            lenHex = headLen + subLen
        return lenHex
    
    @staticmethod
    def oidEncode(oid):
        strHex = str()
        strBit = str()
        arcs = oid.split()
        strHex += Util.convertIntToHex(int(arcs[0]) * 40 + int(arcs[1]))
        
        for arc in arcs[2:]:
            intArc = int(arc)
            if intArc < 128:
                strHex += Util.convertIntToHex(intArc)
            elif intArc >= 128 and intArc < 16384:
                strBit = Util.convertIntToBit(intArc)
                strHex += Util.convertBitToHex('1' + '0' * (14 - len(strBit)) + \
                                          strBit[:-7] + '0' + strBit[-7:])
            elif intArc >= 16384:
                strBit = Util.convertIntToBit(intArc)
                strHex += Util.convertBitToHex('1' + '0' * (21 - len(strBit)) + \
                                          strBit[:-14] + '1' + strBit[-14:-7] + \
                                          '0' + strBit[-7:])
        return strHex
    
    @staticmethod
    def octetStrEncode(strChar):
        return ''.join(map(binascii.b2a_hex, strChar)).upper()
    
    @staticmethod
    def intEncode(intValue):
        
        strHex = ''
        newIntBit = ''
        
        if intValue >= 0:
            
            intValuebinary = Util.convertIntToBit(intValue)
            reminder = len(intValuebinary) % 8
            #padding
            if reminder != 0:
                intValuebinary = intValuebinary.zfill(8*len(intValuebinary)/8 + (8 -reminder) )
            if intValuebinary[0] == '1':
                intValuebinary = '00000000'+intValuebinary
            strHex = Util.convertBitToHex(intValuebinary)
        
        else: # Negative integer
            intHex = hex(intValue)[2:].upper()
            intBit = ''
            for h in intHex:
                intBit += Util.h2b.get(h)
            if len(intBit) % 8 != 0:
                intBit = '0' * (8 - len(intBit) % 8) + intBit
            for i in range(len(intBit)):
                if intBit[0] == '0':
                    newIntBit += '1'
                else:
                    newIntBit += '0'
                intBit = intBit[1:]
            # The next 6 lines add 1 to bit string
            splitedIntBit = newIntBit.rsplit('1')
            if len(newIntBit) == len(splitedIntBit):
                finalIntBit = newIntBit[:-1] + '1'
            else:
                finalIntBit = splitedIntBit[:-1] + '1' + \
                              '0' * (len(newIntBit) - len(splitedIntBit))
            for i in range(len(finalIntBit) / 4):
                strHex += Util.b2h.get(finalIntBit[:4])
                finalIntBit = finalIntBit[4:]
            if strHex[0] < '8':
                strHex = 'FF' + strHex
        return strHex
    
    @staticmethod
    def boolEncode(bool):
        if bool is True:
            return 'FF'
        else:
            return '00'
    
if __name__ == '__main__':
    hoga = Encoder()
    print hoga.intEncode(128)